home *** CD-ROM | disk | FTP | other *** search
- /*
- File: USBKeypad.c
-
- Contains: HID Module for USB Keyboard
-
- Version: xxx put version here xxx
-
- Copyright: © 1997-1998 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #include <Types.h>
- #include <Devices.h>
- #include <processes.h>
- #include <DriverServices.h>
- #include <USB.h>
-
- #include "USBKeypad.h"
-
- usbMacAllyPBStruct myParamBlock;
- usbMacAllyPBStruct shimParamBlock;
-
-
- void InitParamBlock(USBDeviceRef theDeviceRef, USBPB * paramblock);
-
- void InitParamBlock(USBDeviceRef theDeviceRef, USBPB * paramblock)
- {
- paramblock->usbReference = theDeviceRef;
- paramblock->pbVersion = kUSBCurrentPBVersion;
- paramblock->usb.cntl.WIndex = 0;
- paramblock->usbBuffer = nil;
- paramblock->usbStatus = noErr;
- paramblock->usbReqCount = 0;
- paramblock->usb.cntl.WValue = 0;
- paramblock->usbFlags = 0;
- paramblock->usbOther = 0;
- }
-
- static Boolean immediateError(OSStatus err)
- {
- return((err != kUSBPending) && (err != noErr) );
- }
-
- void InitiateTransaction(USBPB *pb)
- {
- register usbMacAllyPBStruct *pMacAllyPB;
- OSStatus myErr;
-
- pMacAllyPB = (usbMacAllyPBStruct *)(pb);
- pMacAllyPB->transDepth++;
- if (pMacAllyPB->transDepth < 0)
- {
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pUSBHIDMacAllyTenKey: transDepth < 0 (initiation)", pMacAllyPB->pb.usbRefcon );
- }
-
- if (pMacAllyPB->transDepth > 1)
- {
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pUSBHIDMacAllyTenKey: transDepth > 1 (initiation)", pMacAllyPB->pb.usbRefcon );
- }
-
- switch(pMacAllyPB->pb.usbRefcon & ~kRetryTransaction)
- {
- case kSetKeyboardLEDs:
- InitParamBlock(pMacAllyPB->deviceRef, &pMacAllyPB->pb);
-
- pMacAllyPB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBInterface);
-
- pMacAllyPB->pb.usb.cntl.BRequest = kHIDRqSetReport;
- pMacAllyPB->pb.usb.cntl.WValue = (kHIDRtOutputReport << 8);
- pMacAllyPB->pb.usb.cntl.WIndex = pMacAllyPB->pInterfaceDescriptor->interfaceNumber;
-
- pMacAllyPB->pb.usbBuffer = (Ptr)&pMacAllyPB->hidReport[0];
- pMacAllyPB->pb.usbReqCount = 1;
-
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
-
- myErr = USBDeviceRequest(&pMacAllyPB->pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pUSBHIDMacAllyTenKey: kSetKeyboardLEDs - immediate error", myErr);
- }
- break;
-
- case kFindInterface:
- InitParamBlock(pMacAllyPB->deviceRef, &pMacAllyPB->pb);
- pMacAllyPB->pb.usb.cntl.WIndex = 0;
- pMacAllyPB->pb.usb.cntl.WValue = 0;
- pMacAllyPB->pb.usbClassType = kUSBHIDInterfaceClass;
- pMacAllyPB->pb.usbSubclass = kUSBNoInterfaceSubClass;
- pMacAllyPB->pb.usbProtocol = kUSBKeyboardInterfaceProtocol;
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBFindNextInterface(pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->pb.usbReference, kUSBInternalErr, "\pMacAlly TenKey Driver: USBFindNextInterface (immediate error)", myErr);
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kOpenDevice:
- InitParamBlock(pMacAllyPB->deviceRef, &pMacAllyPB->pb);
- pMacAllyPB->pb.usb.cntl.WValue = pMacAllyPB->configurationNumber;
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
-
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBOpenDevice(pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->pb.usbReference, kUSBInternalErr, "\pMacAlly TenKey Driver: USBOpenDevice (immediate error)", myErr);
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kNewInterfaceRef:
- InitParamBlock(pMacAllyPB->deviceRef, &pMacAllyPB->pb);
- pMacAllyPB->pb.usb.cntl.WIndex = pMacAllyPB->interfaceNumber;
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
-
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBNewInterfaceRef(pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->pb.usbReference, kUSBInternalErr, "\pMacAlly TenKey Driver: USBNewInterfaceRef (immediate error)", myErr);
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kConfigureInterface:
- InitParamBlock(pMacAllyPB->interfaceRef, &pMacAllyPB->pb);
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
-
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBConfigureInterface(pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->pb.usbReference, kUSBInternalErr, "\pMacAlly TenKey Driver: USBConfigureInterface (immediate error)", myErr);
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kGetReportDescriptor:
- InitParamBlock(pMacAllyPB->deviceRef, &pMacAllyPB->pb);
- pMacAllyPB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBInterface);
- pMacAllyPB->pb.usb.cntl.BRequest = kUSBRqGetDescriptor;
- pMacAllyPB->pb.usb.cntl.WValue = (0x22 << 8) + 1; // get the first report descriptor
- pMacAllyPB->pb.usb.cntl.WIndex = pMacAllyPB->interfaceNumber;
- pMacAllyPB->pb.usbReqCount = 0x66;
- pMacAllyPB->pb.usbBuffer = pMacAllyPB->hidReportDescriptor;
-
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBDeviceRequest(pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->pb.usbReference, kUSBInternalErr, "\pMacAlly TenKey Driver: kGetReportDescriptor - immediate error", myErr);
- }
- break;
-
- case kFindInterruptPipe:
- USBExpertStatus(pMacAllyPB->interfaceRef, "\pUSBHIDMacAllyTenKey: kFindInterruptPipe - interfaceRef", pMacAllyPB->interfaceRef);
- InitParamBlock(pMacAllyPB->interfaceRef, &pMacAllyPB->pb);
- pMacAllyPB->pb.usbFlags = kUSBIn;
- pMacAllyPB->pb.usbClassType = kUSBInterrupt;
-
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBFindNextPipe(&pMacAllyPB->pb);
- if (immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pMacAlly TenKey Driver: kFindInterruptPipe (immediate error)", myErr);
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kReadInterruptPipe:
- InitParamBlock(pMacAllyPB->pipeRef, &pMacAllyPB->pb);
-
- pMacAllyPB->pb.usbBuffer = (Ptr)pMacAllyPB->hidReport;
- pMacAllyPB->pb.usbReqCount = 4;
- pMacAllyPB->pb.usb.cntl.WIndex = pMacAllyPB->interfaceNumber;
-
- pMacAllyPB->pb.usbRefcon |= kCompletionPending;
- pMacAllyPB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBIntRead(&pMacAllyPB->pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pMacAlly TenKey Driver: kReadInterruptPipe (ImmediateError)", myErr);
- }
- break;
-
-
- default:
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pUSBHIDMacAllyTenKey - Transaction completed with bad refcon value", pMacAllyPB->pb.usbRefcon );
- pMacAllyPB->pb.usbRefcon = kUndefined + kReturnFromDriver;
- break;
- }
-
- // At this point the control is returned to the system. If a USB transaction
- // has been initiated, then it will call the Complete procs
- // (below) to handle the results of the transaction.
- }
-
- void TransactionCompletionProc(USBPB *pb)
- {
- unsigned char * errstring;
- register usbMacAllyPBStruct *pMacAllyPB;
- USBPipeState pipeState;
-
- pMacAllyPB = (usbMacAllyPBStruct *)(pb);
- pMacAllyPB->transDepth--;
- if (pMacAllyPB->transDepth < 0)
- {
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pUSBHIDMacAllyTenKey: transDepth < 0 (completion)", pMacAllyPB->pb.usbRefcon );
- }
-
- if (pMacAllyPB->transDepth > 1)
- {
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pUSBHIDMacAllyTenKey: transDepth > 1 (completion)", pMacAllyPB->pb.usbRefcon );
- }
-
- if(pMacAllyPB->pb.usbStatus != noErr) // was there an error?
- {
- switch(pMacAllyPB->pb.usbRefcon & 0x0fff) // yes, so show where the error occurred
- {
- case kFindInterface: errstring = "\pWacom Driver: Error during kFindInterface"; break;
- case kOpenDevice: errstring = "\pWacom Driver: Error during kOpenDevice"; break;
- case kNewInterfaceRef: errstring = "\pWacom Driver: Error during kNewInterfaceRef"; break;
- case kConfigureInterface: errstring = "\pWacom Driver: Error during kConfigureInterface"; break;
- case kGetReportDescriptor: errstring = "\pWacom Driver: Error during kGetReportDescriptor"; break;
- case kFindInterruptPipe: errstring = "\pWacom Driver: Error during kFindInterruptPipe"; break;
- case kReadInterruptPipe: errstring = "\pWacom Driver: Error during kReadInterruptPipe"; break;
- };
- USBExpertFatalError(pMacAllyPB->deviceRef, pMacAllyPB->pb.usbStatus, errstring, (pMacAllyPB->pb.usbRefcon & 0x0fff));
-
- pMacAllyPB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver); // set up to retry the transaction
- pMacAllyPB->pb.usbRefcon |= kRetryTransaction;
- pMacAllyPB->retryCount--;
-
- if ((!pMacAllyPB->retryCount) || (pMacAllyPB->pb.usbStatus == kUSBAbortedError)) // have we exhausted the retries?
- { // or received an abort?
- USBExpertStatus(pMacAllyPB->deviceRef, "\pUSBHIDMacAllyTenKey: Pipe abort or unable to recover from error", pMacAllyPB->deviceRef);
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver; // if so, just exit.
- }
- else // if it didn't abort and there's retries left, then...
- {
- if (pMacAllyPB->pipeRef) // check if the pipe is open.
- {
- USBGetPipeStatusByReference(pMacAllyPB->pipeRef, &pipeState); // yes, so what it's state?
- if (pipeState != kUSBActive) // if it's not active, try to clear it. It might be stalled...
- {
- USBExpertStatus(pMacAllyPB->deviceRef, "\pUSBHIDMacAllyTenKey: Pipe is open and stalled, clearing stall...", pMacAllyPB->deviceRef);
- USBClearPipeStallByReference(pMacAllyPB->pipeRef);
- }
- }
- }
- }
- else
- {
- pMacAllyPB->pb.usbRefcon &= ~kRetryTransaction;
- pMacAllyPB->retryCount = kKeyboardRetryCount;
- }
-
- if (pMacAllyPB->pb.usbRefcon & kCompletionPending)
- {
- pMacAllyPB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver);
- switch(pMacAllyPB->pb.usbRefcon)
- {
- case kSetKeyboardLEDs:
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- break;
-
- case kFindInterface:
- if ((pMacAllyPB->pb.usbClassType == kUSBHIDInterfaceClass) &&
- (pMacAllyPB->pb.usbSubclass == kUSBNoInterfaceSubClass) &&
- (pMacAllyPB->pb.usbProtocol == kUSBKeyboardInterfaceProtocol))
- {
- pMacAllyPB->pb.usbRefcon = kOpenDevice;
- pMacAllyPB->interfaceNumber = pMacAllyPB->pb.usb.cntl.WIndex;
- pMacAllyPB->configurationNumber = pMacAllyPB->pb.usb.cntl.WValue;
- }
- else
- {
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kOpenDevice:
- pMacAllyPB->pb.usbRefcon = kNewInterfaceRef;
- break;
-
- case kNewInterfaceRef:
- pMacAllyPB->interfaceRef = pMacAllyPB->pb.usbReference;
- pMacAllyPB->pb.usbRefcon = kConfigureInterface;
- break;
-
- case kConfigureInterface:
- pMacAllyPB->pb.usbRefcon = kFindInterruptPipe;
- break;
-
- case kGetReportDescriptor:
- pMacAllyPB->pb.usbRefcon = kFindInterruptPipe;
- break;
-
- case kFindInterruptPipe:
- if ((pMacAllyPB->pb.usbClassType == kUSBInterrupt) &&
- (pMacAllyPB->pb.usbFlags == kUSBIn))
- {
- pMacAllyPB->hidReportSize = pMacAllyPB->pb.usb.cntl.WValue;
- pMacAllyPB->pipeRef = pMacAllyPB->pb.usbReference;
- pMacAllyPB->pb.usbRefcon = kReadInterruptPipe;
- }
- else
- {
- pMacAllyPB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kReadInterruptPipe:
- //DebugStr("\pMacAlly read completed");
- ProcessInterruptReport(pMacAllyPB->hidReport);
- pMacAllyPB->pb.usbRefcon = kReadInterruptPipe;
- break;
-
- default:
- USBExpertFatalError(pMacAllyPB->deviceRef, kUSBInternalErr, "\pUSBHIDMacAllyTenKey - Transaction completed with bad refcon value", pMacAllyPB->pb.usbRefcon );
- pMacAllyPB->pb.usbRefcon = kUndefined + kReturnFromDriver;
- break;
- }
- }
- if (!(pMacAllyPB->pb.usbRefcon & kReturnFromDriver))
- InitiateTransaction(pb);
- }
-
-
- void DriverEntry(USBDeviceRef device, USBDeviceDescriptorPtr pDesc, UInt32 busPowerAvailable)
- {
- #pragma unused (busPowerAvailable)
-
- static Boolean beenThereDoneThat = false;
-
- if(beenThereDoneThat)
- {
- USBExpertFatalError(device, kUSBInternalErr, "\pUSBHIDMacAllyTenKey is not reentrant", 12);
- return;
- }
- beenThereDoneThat = true;
-
- // DebugStr("\pIn Keyboard Module Interface entry routine");
- shimParamBlock.deviceDescriptor = *pDesc;
- shimParamBlock.transDepth = 0;
- shimParamBlock.retryCount = kKeyboardRetryCount;
- shimParamBlock.deviceRef = device;
- shimParamBlock.interfaceRef = 0;
- shimParamBlock.pipeRef = 0;
-
- shimParamBlock.deviceRef = device;
- shimParamBlock.interfaceRef = nil;
- shimParamBlock.pipeRef = nil;
-
- InitParamBlock(device, &shimParamBlock.pb);
- shimParamBlock.pb.pbLength = sizeof(usbMacAllyPBStruct);
- shimParamBlock.pb.usbRefcon = 0;
-
- myParamBlock.deviceDescriptor = *pDesc;
- myParamBlock.transDepth = 0;
- myParamBlock.retryCount = kKeyboardRetryCount;
- myParamBlock.deviceRef = device;
- myParamBlock.interfaceRef = 0;
- myParamBlock.pipeRef = 0;
-
- myParamBlock.deviceRef = device;
- myParamBlock.interfaceRef = nil;
- myParamBlock.pipeRef = nil;
-
- myParamBlock.sendRawReportFlag = false;
- myParamBlock.hidEmulationInit = false;
-
- InitParamBlock(device, &myParamBlock.pb);
- myParamBlock.pb.pbLength = sizeof(usbMacAllyPBStruct);
- myParamBlock.pb.usbRefcon = kFindInterface; /* Start with setting the interface protocol */
-
-
- USBHIDControlDevice(kHIDEnableDemoMode,0);
- InitiateTransaction(&myParamBlock.pb);
- }
-
-
-
-